package com.ruoyi.fire.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.ResponseEntityInfo;
import com.ruoyi.common.enums.PushStatus;
import com.ruoyi.common.enums.RequestMapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.*;
import com.ruoyi.fire.domain.TBuilding;
import com.ruoyi.fire.domain.TUnit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.fire.mapper.TFloorMapper;
import com.ruoyi.fire.domain.TFloor;
import com.ruoyi.fire.service.ITFloorService;
import org.springframework.util.CollectionUtils;

/**
 * 楼层信息Service业务层处理
 *
 * @author ruoyi
 * @date 2025-11-02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TFloorServiceImpl extends ServiceImpl<TFloorMapper, TFloor> implements ITFloorService {
    @Autowired
    private TFloorMapper tFloorMapper;
    private final TBuildingServiceImpl buildingService;
    // 添加线程池注入
    private final Executor threadPoolTaskExecutor;
    private final RequestService requestService;

    /**
     * 查询楼层信息
     *
     * @param id 楼层信息主键
     * @return 楼层信息
     */
    @Override
    public TFloor selectTFloorById(String id) {
        return tFloorMapper.selectTFloorById(id);
    }

    /**
     * 查询楼层信息列表
     *
     * @param tFloor 楼层信息
     * @return 楼层信息
     */
    @Override
    public List<TFloor> selectTFloorList(TFloor tFloor) {
        List<TFloor> tFloors = tFloorMapper.selectTFloorList(tFloor);
        if (!CollectionUtils.isEmpty(tFloors)) {
            for (TFloor floor : tFloors) {
                floor.setBuilding(buildingService.getById(floor.getBgId()));
            }
        }
        return tFloors;
    }

    /**
     * 新增楼层信息
     *
     * @param tFloor 楼层信息
     * @return 结果
     */
    @Override
    public boolean insertTFloor(TFloor tFloor) {

        TBuilding tBuilding = buildingService.getById(tFloor.getBgId());

        boolean isNetworkedUnit = tBuilding.getBuildingId() != null;

        if (isNetworkedUnit) {
            tBuilding.setPushStatus(PushStatus.PUSH_FAILED.getCode());
        } else {
            tBuilding.setPushStatus(PushStatus.NOT_PUSHED.getCode());
        }

        Long userId = SecurityUtils.getUserId();
        String username = SecurityUtils.getUsername();
        tFloor.setCreateBy(username);
        tFloor.setCreateTime(DateUtils.getNowDate());
        tFloor.setCreateUserId(userId);

        boolean result = save(tFloor);
        if (result && isNetworkedUnit) {
            // 提交至线程池异步处理推送逻辑
            threadPoolTaskExecutor.execute(() -> {
                try {
                    Map<String, Object> unitMap = ConvertToMap.convertObjectToMap(tFloor);
                    unitMap.remove("id");
                    unitMap.put("building_id", tBuilding.getBuildingId());
                    ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.ADD_FLOOR, unitMap);

                    TFloor floor = JSON.parseObject(responseEntityInfo.getData().toString(), TFloor.class);

                    LambdaUpdateWrapper<TFloor> updateWrapper = Wrappers.lambdaUpdate(TFloor.class)
                            .eq(TFloor::getId, tFloor.getId())
                            .set(TFloor::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                            .set(TFloor::getFloorId, floor.getId());
                    update(updateWrapper);
                } catch (Exception e) {
                    log.error("推送楼层失败: id={}, error={}", tFloor.getId(), e.getMessage(), e);
                    // 更新推送状态为失败
                    LambdaUpdateWrapper<TFloor> failUpdateWrapper = Wrappers.lambdaUpdate(TFloor.class)
                            .eq(TFloor::getId, tFloor.getId())
                            .set(TFloor::getPushStatus, PushStatus.PUSH_FAILED.getCode());
                    update(failUpdateWrapper);
                }
            });
        }
        return result;
    }

    /**
     * 修改楼层信息
     *
     * @param tFloor 楼层信息
     * @return 结果
     */
    @Override
    public int updateTFloor(TFloor tFloor) {

        TBuilding tBuilding = buildingService.getById(tFloor.getBgId());

        boolean isNetworkedUnit = tBuilding.getBuildingId() == null;

        // 设置推送状态
        if (!isNetworkedUnit) {
            tFloor.setPushStatus(PushStatus.NOT_PUSHED.getCode());
        }

        tFloor.setUpdateTime(DateUtils.getNowDate());
        int result = tFloorMapper.updateTFloor(tFloor);

        if (result > 0 && isNetworkedUnit) {
            // 提交至线程池异步处理推送逻辑
            threadPoolTaskExecutor.execute(() -> {
                try {
                    RequestMapper requestMapper = tFloor.getFloorId() != null ? RequestMapper.UPDATE_FLOOR : RequestMapper.ADD_FLOOR;
                    Map<String, Object> floorMap = ConvertToMap.convertObjectToMap(tFloor);
                    if (tFloor.getFloorId() != null) {
                        floorMap.put("id", tFloor.getFloorId());
                    } else {
                        floorMap.remove("id");
                    }

                    ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(requestMapper, floorMap);

                    TFloor floor = JSON.parseObject(responseEntityInfo.getData().toString(), TFloor.class);

                    LambdaUpdateWrapper<TFloor> updateWrapper = Wrappers.lambdaUpdate(TFloor.class)
                            .eq(TFloor::getId, tFloor.getId())
                            .set(TFloor::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                            .set(TFloor::getFloorId, floor.getId());
                    update(updateWrapper);
                } catch (Exception e) {
                    log.error("推送联网层信息失败: floorId={}, error={}", tFloor.getId(), e.getMessage(), e);

                    // 更新推送状态为失败
                    LambdaUpdateWrapper<TFloor> failUpdateWrapper = Wrappers.lambdaUpdate(TFloor.class)
                            .eq(TFloor::getId, tFloor.getId())
                            .set(TFloor::getPushStatus, PushStatus.PUSH_FAILED.getCode());
                    update(failUpdateWrapper);
                }
            });
        }
        return result;
    }

    /**
     * 批量删除楼层信息
     *
     * @param ids 需要删除的楼层信息主键
     * @return 结果
     */
    @Override
    public int deleteTFloorByIds(String[] ids) {
        return tFloorMapper.deleteTFloorByIds(ids);
    }

    /**
     * 删除楼层信息信息
     *
     * @param id 楼层信息主键
     * @return 结果
     */
    @Override
    public int deleteTFloorById(String id) {
        return tFloorMapper.deleteTFloorById(id);
    }

    /**
     * 同步楼层信息
     *
     * @param id 单位信息主键
     * @return 结果
     */
    @Override
    public boolean pushTUnit(String id) {
        TFloor tFloor = getById(id);
        if (tFloor == null) {
            log.warn("楼层信息不存在，id={}", id);
            return false;
        }

        boolean isNew = tFloor.getFloorId() == null || tFloor.getFloorId().equals("");

        doPush(isNew, tFloor);
        return true;
    }

    /**
     * 远程删除楼层信息
     *
     * @param floorId 楼层信息主键
     * @return 删除结果
     */
    @Override
    public boolean remoteDeletion(String floorId) {
        TFloor floor = getById(floorId);
        if (StringUtils.isNotNull(floor)) {
            Map<String, Object> params = new HashMap<>();
            params.put("id", floor.getFloorId());
            ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.FLOOR_DELETE, params);

            if (responseEntityInfo.getErrno() == 0) {
                LambdaUpdateWrapper<TFloor> updateWrapper = Wrappers.lambdaUpdate(TFloor.class);
                updateWrapper.set(TFloor::getFloorId, "");
                updateWrapper.set(TFloor::getPushStatus, PushStatus.NOT_PUSHED.getCode());
                updateWrapper.eq(TFloor::getId, floor.getId());
                update(updateWrapper);
            } else {
                throw new ServiceException("远程删除失败： " + responseEntityInfo.getErrmsg());
            }
        }
        return true;
    }

    /**
     * 先删除远程在删除本地信息
     *
     * @param floorId 楼层信息主键
     * @return 删除结果
     */
    @Override
    public int removeByFloorId(String floorId) {
        TFloor floor = getById(floorId);
        if (StringUtils.isNotNull(floor) && StringUtils.isNotEmpty(floor.getFloorId())) {
            Map<String, Object> params = new HashMap<>();
            params.put("id", floor.getFloorId());
            ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.FLOOR_DELETE, params);

            if (responseEntityInfo.getErrno() == 0) {
                removeById(floorId);
            }
            throw new ServiceException("远程删除失败： " + responseEntityInfo.getErrmsg());
        }
        return 0;
    }


    private void doPush(boolean isNew, TFloor floor) {
        String requestType = isNew ? "新增楼层信息" : "修改楼层信息";
        log.info("开始{}推送，unitId={}", requestType, floor.getId());

        Map<String, Object> floorMap = ConvertToMap.convertObjectToMap(floor);
        if (isNew) {
            floorMap.remove("id");
        } else {
            floorMap.put("id", floor.getFloorId());
        }

        RequestMapper mapper = isNew ? RequestMapper.ADD_FLOOR : RequestMapper.UPDATE_FLOOR;
        ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(mapper, floorMap);

        if (responseEntityInfo.getErrno() != 0) {
            log.error("{}推送失败，unitId={}, error={}", requestType, floor.getId(), responseEntityInfo.getErrmsg());

            // 推送失败
            LambdaUpdateWrapper<TFloor> failUpdateWrapper = Wrappers.lambdaUpdate(TFloor.class)
                    .eq(TFloor::getId, floor.getId())
                    .set(TFloor::getPushStatus, PushStatus.PUSH_FAILED.getCode());

            update(failUpdateWrapper);
            throw new ServiceException(responseEntityInfo.getErrmsg());
        }

        TFloor floorResult = JSON.parseObject(responseEntityInfo.getData().toString(), TFloor.class);

        LambdaUpdateWrapper<TFloor> updateWrapper = Wrappers.lambdaUpdate(TFloor.class)
                .eq(TFloor::getId, floor.getId())
                .set(TFloor::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                .set(TFloor::getFloorId, floorResult.getId());

        update(updateWrapper);

        log.info("{}推送成功，unitId={}", requestType, floor.getId());
    }
}
